
from PyQt5.QtWidgets import *
from DNACenter import *
from MyTreeWidgetItem import MyTreeItem
from PyQt5 import QtGui, QtCore
from PyQt5.QtGui import QIcon, QStandardItem, QStandardItemModel
import threading  # 需要开一个线程监视处理是否完成
import time
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class StackMainWindow(QWidget):
    def __init__(self, host,username,
                 password,version='v1'):
        super(StackMainWindow, self).__init__()
        # 实例化DNAC
        self.myDNAC = DNAC(host,username,
                 password,version)

        # 设置窗口初始位置和大小
        self.setGeometry(200, 300, 1350, 600)
        self.setWindowTitle('Efficient Manager')
        self.setWindowIcon(QIcon("./Pic/logo.jpg"))
        self.setMaximumSize(1350, 600)
        self.setMinimumSize(1350, 600)

        window_pale = QtGui.QPalette()
        window_pale.setBrush(self.backgroundRole(),
                                 QtGui.QBrush(QtGui.QPixmap("./Pic/mainBack.jpg")))

        self.setPalette(window_pale)

        self.leftlist = QListView()
        self.leftlist.setStyleSheet("QListView{\n"
        "    background:#6C6C6C;\n"
        "    color:white;\n"
        "    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);font-size:18px;border-radius: 10px;font-family: 微软雅黑;\n"
        "}\n"
        "QListView:hover{                    \n"
        "    background:#9D9D9D;\n"
        "}\n")

        self.item1 = QStandardItem(QIcon("./Pic/f1.png"), "Check  Facilities")
        self.item2 = QStandardItem(QIcon("./Pic/f2.png"), "Path Trace")
        self.item3 = QStandardItem(QIcon("./Pic/f3.png"), "To Be Continued")
        self.item1.setTextAlignment(Qt.AlignCenter)
        self.item2.setTextAlignment(Qt.AlignCenter)
        self.item3.setTextAlignment(Qt.AlignCenter)
        model = QStandardItemModel()
        model.appendRow(self.item1)
        model.appendRow(self.item2)
        model.appendRow(self.item3)
        self.leftlist.setModel(model)
        # 设置显示那个
        self.leftlist.clicked.connect(self.display)
        # 创建三个小控件
        self.stack1=QWidget()
        self.stack2=QWidget()
        self.stack3=QWidget()
        self.stack1UI()
        self.stack2UI()
        self.stack3UI()
        # 在QStackedWidget对象中填充了三个子控件
        self.stack=QStackedWidget(self)
        self.stack.addWidget(self.stack1)
        self.stack.addWidget(self.stack2)
        self.stack.addWidget(self.stack3)
        # 水平布局，添加部件到布局中
        HBox=QHBoxLayout()
        HBox.addWidget(self.leftlist)
        HBox.addWidget(self.stack)
        HBox.setStretchFactor(self.leftlist,1)
        HBox.setStretchFactor(self.stack,5)
        self.setLayout(HBox)

    def stack1UI(self):
        print("第一个界面")
        op=QGraphicsOpacityEffect()
        op.setOpacity(0.85)
        # --------建树--------
        self.tree = QTreeWidget()
        self.tree.setStyleSheet("QTreeWidget{\n"
        "    background:#6C6C6C;\n"
        "    color:white;\n"
        "    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);font-size:18px;border-radius: 10px;font-family: 微软雅黑;\n"
        "}\n")
        self.tree.setGraphicsEffect(op)
        self.tree.setColumnCount(1)
        # 指定列的标签
        self.tree.setHeaderLabels(['INFO'])
        self.tree.setColumnWidth(0, 100)
        # 子节点NDRoot  QTreeWidgetItem（参数）  在参数下面创建子条目 返回子条目对象
        self.NDRoot = MyTreeItem(self.tree)
        self.NDRoot.setText(0, 'Network-Devices')

        # 添加子节点HRoot
        self.HRoot = MyTreeItem(self.tree)
        self.HRoot.setText(0, 'Host')

        # 绑定事件函数
        self.tree.clicked.connect(self.onTreeClicked)

        # --------右侧状态区--------
        stateText = QTextEdit()

        stateText.setStyleSheet("QTextEdit{\n"
        "    background:#6C6C6C;\n"
        "    color:white;\n"
        "    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);font-size:18px;border-radius: 10px;font-family: 微软雅黑;\n"
        "}\n"
        "QTextEdit:hover{                    \n"
        "    background:#9D9D9D;\n"
        "}\n")
        stateText.setDisabled(1)
        stateText.setText("hello world!")

        # --------右侧暂记--------
        self.tempDetial = stateText


        # --------嵌套布局（由小到大）--------
        # 装载下半部分(内容)
        self.stack1ContentLayout = QHBoxLayout()
        self.stack1ContentLayout.addWidget(self.tree)
        self.stack1ContentLayout.addWidget(stateText)
        self.stack1ContentLayout.setStretchFactor(self.tree, 7)
        self.stack1ContentLayout.setStretchFactor(stateText, 11)

        # 装载所有
        mainLayout = QVBoxLayout()
        mainLayout.addLayout(self.stack1ContentLayout)
        # 设置主布局！！！！！！！！这里不是stack1的话不匹配！
        self.stack1.setLayout(mainLayout)

        self.initTreeContent()

    def stack2UI(self):
        print("第二个界面")
        # 实例化布局
        self.stack2mainLayout = QVBoxLayout()
        # # 设置主布局！！！！！！！！这里才是关键
        # 创建多行文本框
        labels = ['number', 'type', 'ip']
        self.textEdit = QTextEdit()
        self.stack2TempU = self.textEdit
        self.textEdit.setStyleSheet("QTextEdit{\n"
        "    background:#6C6C6C;\n"
        "    color:white;\n"
        "    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);font-size:18px;border-radius: 10px;font-family: 微软雅黑;\n"
        "}\n"
        "QLabel:hover{                    \n"
        "    background:#9D9D9D;\n"
        "}\n")
        # self.textEdit.setAlignment(Qt.AlignCenter)
        self.textEdit2 = QTextEdit()
        self.textEdit2.setStyleSheet("QTextEdit{\n"
        "    background:#6C6C6C;\n"
        "    color:white;\n"
        "    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);font-size:18px;border-radius: 10px;font-family: 微软雅黑;\n"
        "}\n"
        "QLabel:hover{                    \n"
        "    background:#9D9D9D;\n"
        "}\n")

        # 创建两个按钮
        self.btnPress1 = QPushButton('查询当前可用IP')
        self.btnPress2 = QPushButton('点击输入起点与终点（输入序号即可）')
        self.btnPress1.setStyleSheet("QPushButton{\n"
        "    background:#6C6C6C;\n"
        "    color:white;\n"
        "    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);font-size:18px;border-radius: 10px;font-family: 微软雅黑;\n"
        "}\n"
        "QPushButton:hover{                    \n"
        "    background:#9D9D9D;\n"
        "}\n"
        "QPushButton:pressed{\n"
        "    border: 1px solid #3C3C3C!important;\n"
        "}")
        self.btnPress2.setStyleSheet("QPushButton{\n"
        "    background:#6C6C6C;\n"
        "    color:white;\n"
        "    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);font-size:18px;border-radius: 10px;font-family: 微软雅黑;\n"
        "}\n"
        "QPushButton:hover{                    \n"
        "    background:#9D9D9D;\n"
        "}\n"
        "QPushButton:pressed{\n"
        "    border: 1px solid #3C3C3C!important;\n"
        "}")

        # 相关控件添加到垂直布局中
        self.stack2mainLayout.addWidget(self.textEdit)
        self.stack2mainLayout.addWidget(self.btnPress1)
        self.stack2mainLayout.addWidget(self.btnPress2)
        self.stack2mainLayout.addWidget(self.textEdit2)

        # 将按钮的点击信号与相关的槽函数进行绑定，点击即触发
        self.btnPress1.clicked.connect(self.btnPress1_clicked)
        self.btnPress2.clicked.connect(self.btnPress2_clicked)
        # 设置布局
        self.stack2.setLayout(self.stack2mainLayout)

    def stack2CreateTable(self, labels, lists):
        # 设置数据层次结构
        model = QStandardItemModel()
        # 设置水平方向四个头标签文本内容
        model.setHorizontalHeaderLabels(labels)

        for i in lists:
            # 筛选！
            model.appendRow([QStandardItem(i[1]), QStandardItem(i[2])])


        tableView = QTableView()
        tableView.setStyleSheet("QTableView{\n"
                                "    background:#6C6C6C;\n"
                                "    color:white;\n"
                                "    box-shadow: 1px 1px 3px rgba(0,0,0,0.3);font-size:18px;border-radius: 10px;font-family: 微软雅黑;\n"
                                "}\n"
                                )
        tableView.setModel(model)
        # 水平方向标签拓展剩下的窗口部分，填满表格
        tableView.horizontalHeader().setStretchLastSection(True)
        # 水平方向，表格大小拓展到适当的尺寸
        tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        return tableView

    def stack3UI(self):
        print("第三个界面")
        mainLayout = QVBoxLayout()
        # # 设置主布局！！！！！！！！这里才是关键
        self.stack3.setLayout(mainLayout)

    def display(self, index):
        # 设置当前可见的选项卡的索引
        i=index.row()
        self.stack.setCurrentIndex(i)
        print(i)

    def onTreeClicked(self, index):
        # 这里
        item = self.tree.currentItem()
        if item is not None:
            print(index.row())
            print('key=%s' % (item.text(0)))
            self.stack1ContentLayout.removeWidget(self.tempDetial)
            self.tempDetial.setVisible(False)
            self.stack1ContentLayout.addWidget(item.dataView)
            self.stack1ContentLayout.setStretchFactor(item.dataView, 11)
            item.dataView.setVisible(True)
            self.tempDetial = item.dataView

    def initTreeContent(self):
        print("hello world!")
        device_dict = self.myDNAC.get_device_list()
        host_dict = self.myDNAC.get_host()

        for device in device_dict:
            NDCase = MyTreeItem(self.NDRoot, device)

            if device['hostname'] is None:
                NDCase.setText(0, 'UNKNOWN')
            else:
                NDCase.setText(0, device['hostname'])


            INode = MyTreeItem(NDCase)
            INode.setText(0, 'Interfaces')
            VNode = MyTreeItem(NDCase)
            VNode.setText(0, 'Vlans')

            print("Fetching Interfaces for Device Id ----> {}".format(device['id']))
            interfaces_info_dict = self.myDNAC.get_device_int(device['id'])
            for interface in interfaces_info_dict:
                ICase = MyTreeItem(INode, interface)
                ICase.setText(0, interface['portName'])

                VCase = MyTreeItem(VNode)
                VCase.setText(0, interface['vlanId'])

        for host in host_dict:
            HCase = MyTreeItem(self.HRoot, host)
            HCase.setText(0, host['hostIp'])

    def btnPress1_clicked(self):
        # 以文本的形式输出到多行文本框
        IP_list = self.myDNAC.get_host_and_device()

        table = self.stack2CreateTable(['type', 'ip'], IP_list)

        self.stack2mainLayout.replaceWidget(self.stack2TempU, table)
        del self.stack2TempU
        self.stack2TempU = table

    def btnPress2_clicked(self):
        self.textEdit2.clear()
        text_tuple = QInputDialog.getText(self, "起点与终点的序号", "请输入序号", text="1;3")


        if text_tuple[1]:
            a,b = text_tuple[0].split(';')
            if a.isdigit() and b.isdigit():
                time.sleep(0.3)
                self.processingTrack(text_tuple[0])
            else:
                QMessageBox.warning(self, "警告", " 您的输入无效，请重新输入！")
                return

        else:
            pass

    def processingTrack(self, text):
        start_ip, end_ip = text.split(';')
        nd_list = self.myDNAC.get_host_and_device()
        numb = len(nd_list)
        if int(start_ip) > numb or int(end_ip) > numb:
            QMessageBox.warning(self, "警告", " 您的输入无效，请重新输入！")
            return

        path = self.myDNAC.path_track(start_ip, end_ip, nd_list)
        path_1 = path["networkElementsInfo"]

        if len(path_1):
            print_str = ''
            for i in range(0, len(path_1)):
                try:
                    print_str += "\n                                                         " \
                                 "                     {}:{}".format(path_1[i]['name'], path_1[i]['ip'])
                except:
                    print_str += "\n                                                         " \
                                 "                     {}:{}".format(path_1[i]['type'], path_1[i]['ip'])
                if i is not len(path_1) - 1:
                    print_str += '\n                                                         ' \
                                 '                                      ↓↓↓'

            print(print_str)
            self.textEdit2.setText(print_str+'\n\n                                                                              ------ End of path trace ! ------')  # 要是thread的话，这里不知道为啥会触发exit.解决了
            print('Done!')
        else:
            self.textEdit2.setText("        Unable to find the full path. No traceroute or netflow information was found. The path calculation failed.\n                                                                              ------ End of path trace ! ------")
            print('Done!')


if __name__ == '__main__':
    app=QApplication(sys.argv)
    demo=StackMainWindow("sandboxdnac.cisco.com:443","devnetuser","Cisco123!")
    demo.show()
    sys.exit(app.exec_())